package com.fingard.dsp.bank.directbank.chinaums01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.RefundState;
import com.fingard.dsp.bank.directbank.bankInterface.IRecRefund;
import com.fingard.dsp.bank.directbank.chinaums01.wsdl.TransactionOntimeServiceImpl;
import com.fingard.dsp.bank.directbank.chinaums01.wsdl.TransactionOntimeServiceImplServiceLocator;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsRecRefund;
import com.fingard.text.StringHelper;

import java.util.Date;
import java.util.HashMap;

/**
 * 银联商务一码付退款
 *
 * @author Cruise
 * @date 2018/11/02
 */
public class ChinaUMS01RecRefund extends ChinaUMS01Base implements IRecRefund {
    @Override
    public RetAtsRecRefund submitRecRefund(ReqRecRefund p_reqRef) throws Exception {
        if (getBankConfig().getValueAsBool("useNewRefund")) {
            return submitRecRefundGoods(p_reqRef);
        } else {
            return submitRecRefunds(p_reqRef);
        }
    }

    public RetAtsRecRefund submitRecRefunds(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;
        retAts.refundNo = p_reqRef.refundNo;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();

                mapParams.put("msgId", "");/* 消息ID */
                mapParams.put("requestTimestamp", Format.DateTimeFormat.format(new Date())); /* 报文请求时间 (格式:yyyy-MM-dd HH:mm:ss)*/
                mapParams.put("srcReserve", "");/* 请求系统预留字段 */
                mapParams.put("merOrderId", p_reqRef.oriRdSeq);/* 商户原交易订单号 */
                mapParams.put("instMid", "YUEDANDEFAULT"); /* 业务类型 */
                mapParams.put("mid", actItem.merchantId);/* 商户号 */
                mapParams.put("tid", getTerminalNum());/* 终端号 */
                mapParams.put("refundAmount", StringHelper.amountMultiply100(p_reqRef.amount));/* 要退货的金额 */
                mapParams.put("refundOrderId", p_reqRef.refundNo);/* 退款订单号 */
                mapParams.put("platformAmount", "");/* 平台商户退款分账金额 */
                mapParams.put("refundDesc", p_reqRef.decription);/* 退货说明 */
                mapParams.put("billDate", Format.Date10Format.format(p_reqRef.getOriTransDate())); /* 账单日期 (格式yyyy-MM-dd) */
                mapParams.put("msgType", "bills.refund"); /* 消息类型 */
                mapParams.put("msgSrc", getMsgSrc()); /* 消息来源 */

//                mapParams.put("billNo", p_reqRef.oriRdSeq); /* 账单号 */
//                mapParams.put("signType", "MD5"); /* 签名算法 */

                String bankFrontUrl = actItem.serverURLMap.get("submitSZRecRefund");
                if (StringHelper.isNullOrEmpty(bankFrontUrl)) {
                    bankFrontUrl = bankFront.getUrl("submitRecRefund");
                }
                String postReqStr = JSON.toJSONString(mapParams);
                String tmpStrRet = querySend(bankFrontUrl, postReqStr, actItem);


                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    if (tmpStrRet.contains("{")) {
                        JSONObject tmpJsonResp = JSON.parseObject(tmpStrRet);

                        retAts.respCode = "0";
                        retAts.respInfo = tmpJsonResp.getString("errMsg");

                        String status = "";
                        String errCode = tmpJsonResp.getString("errCode");
                        String refundState = tmpJsonResp.getString("refundStatus");
                        if (StringHelper.hasAnyChar(refundState)) {
                            status = StringHelper.joinNotEmpty("+", errCode, refundState);
                            retAts.oriOppOrderNo = tmpJsonResp.getString("refundOrderId");
                            retAts.oppRefundNo = tmpJsonResp.getString("refundTargetOrderId");
                        } else {
                            status = errCode;
                        }

                        if ("ORDER_PROCESSING".equals((errCode))) {
                            retAts.refundState = RefundState.REFUND_PAYING;
                        } else if ("SUCCESS".equals(errCode)) {
                            retAts.refundState = RefundState.REFUND_SUCCESS;
                        } else {
                            retAts.refundState = RefundState.REFUND_FAIL;
                        }

                        retAts.originalCode = status;
                        String originalInfo = tmpJsonResp.getString("errMsg");
                        if (StringHelper.isNullOrEmpty(originalInfo)) {
                            originalInfo = "SUCCESS";
                        }
                        retAts.originalInfo = originalInfo;
                        retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", status);
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "银联响应数据格式非法";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsRecRefund submitRecRefundGoods(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
            if (actItem != null) {
                StringBuilder record = new StringBuilder();

                record.append(actItem.merchantId).append(",");//0：商户编号（必填）
                record.append("消费").append(",");//1：交易类型（必填：“消费”）
                record.append("0000").append(",");//2：卡号（必填）
                record.append(Format.Date8Format.format(Format.DateTimeFormat.parse(p_reqRef.oriTransDate))).append(",");//3：原始交易日期（必填：“YYYYMMDD”）
                record.append(p_reqRef.totalAmt).append(",");//4：原始交易金额（必填：单位元）
                record.append(p_reqRef.oriRdSeq).append(",");//5：检索参考号	（必填：12位）
                record.append(p_reqRef.amount).append(",");//6: 退货金额（必填：单位元）
                record.append("1").append(",");//7: 退货资金支付途径（必填：0=从商户余额冻结、1=待转款冲抵）
                record.append("").append(",");//8: 联系人（可选）
                record.append("").append(",");//9: 联系电话（可选）
                record.append("").append(",");//10:申请原因（可选）
                record.append(bankFront.org).append(",");//11:机构编号 （可选）
                record.append("1").append(",");//12:业务类型 （必填：根据商户多应用类型填写）
                record.append("1").append(",");//13: 扣款渠道（必填扣款渠道标志 1:传统银联卡）
                record.append("").append(",");//14:备注字段1（可选）
                record.append("").append(",");//15:备注字段2（可选）
                record.append("").append(",");//16:备注字段3（可选）
                record.append("").append(",");//17:备注字段4（可选）
                record.append(p_reqRef.refundNo);//18:商户退货订单号（可选,如填写对于多笔同一个订单号的请求,将只会接收第一笔请求）

                String url = bankFront.getUrl("submitRecRefundGoods");

                System.setProperty("javax.net.ssl.trustStore", actItem.ownKeyStorePath);
                System.setProperty("javax.net.ssl.trustStorePassword", actItem.ownKeyPassword);
                System.setProperty("javax.net.ssl.keyStore", actItem.oppCertFilePath);
                System.setProperty("javax.net.ssl.keyStorePassword", actItem.saltKey);
                TransactionOntimeServiceImplServiceLocator service = new TransactionOntimeServiceImplServiceLocator();
                service.setTransactionOntimeServiceEndpointAddress(url);
                TransactionOntimeServiceImpl client = service.getTransactionOntimeService();

                WriteBankLogLn("发送银行的record值为：" + record.toString());
                WriteBankLogLn("发送银行的地址为值为：" + url);
                String tmpStrRet = client.applyGoodsReturnSsl(actItem.userCode, actItem.userFlag, record.toString());
                WriteBankLogStep3(tmpStrRet);

                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    if (tmpStrRet.length() == 18) {
                        String status = tmpStrRet.substring(0,2);
                        if ("00".equals(status) || "01".equals(status) || "20".equals(status)) {
                            retAts.refundState = RefundState.REFUND_PAYING;
                        } else if ("02".equals(status) || "04".equals(status) || "21".equals(status)) {
                            retAts.refundState = RefundState.REFUND_FAIL;
                        } else if ("09".equals(status)) {
                            retAts.refundState = RefundState.REFUND_SUCCESS;
                        }
                        retAts.respCode = "0";
                        retAts.respInfo = "";
                        retAts.originalCode = status;
                        retAts.refundNo = tmpStrRet.substring(2);
                        retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", status);
                    } else {
                        retAts.respCode = "0";
                        retAts.respInfo = "申请失败";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }

    @Override
    /* refundStatus取值说明
     * 取值           描述                      备注
     * UNKNOWN  不明确的交易状态  需要调退款查询接口确认退款结果
     * SUCCESS      退款成功
     * FAIL          退款失败
     * PROCESSING   退款处理中     需要调退款查询接口确认退款结果
     */
    public RetAtsQryRecRefund queryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        if (getBankConfig().getValueAsBool("useNewRefund")) {
            return queryRecRefundGoods(p_reqQryRef);
        } else {
            return queryRecRefunds(p_reqQryRef);
        }
    }

    public RetAtsQryRecRefund queryRecRefunds(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("msgId", "");//消息ID
                mapParams.put("requestTimestamp", Format.DateTimeFormat.format(new Date()));//报文请求时间 格式yyyy-MM-dd HH:mm:ss
                mapParams.put("srcReserve", "");//请求系统预留字段
                mapParams.put("merOrderId", p_reqQryRef.refundNo);//商户退货订单号
                mapParams.put("instMid", "YUEDANDEFAULT");//业务类型
                mapParams.put("mid", actItem.merchantId);//商户号
                mapParams.put("tid", getTerminalNum());//终端号

                String bankFrontUrl = actItem.serverURLMap.get("querySZRecRefund");
                if (StringHelper.isNullOrEmpty(bankFrontUrl)) {
                    bankFrontUrl = bankFront.getUrl("queryRecRefund");
                }
                String postReqStr = JSON.toJSONString(mapParams);
                String tmpStrRet = querySend(bankFrontUrl, postReqStr, actItem);

                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    if (tmpStrRet.contains("{")) {
                        JSONObject tmpJsonResp = JSON.parseObject(tmpStrRet);

                        retAts.respCode = "0";
                        retAts.respInfo = tmpJsonResp.getString("errMsg");

                        String status = "";
                        String errCode = tmpJsonResp.getString("errCode");

                        if ("SUCCESS".equals(errCode)) {
                            String refundState = tmpJsonResp.getString("refundStatus");
                            status = StringHelper.joinNotEmpty("+", errCode, refundState);
                            if ("SUCCESS".equals(refundState)) {
                                retAts.refundState = RefundState.REFUND_SUCCESS;
                            } else if ("FAIL".equals(refundState)) {
                                retAts.refundState = RefundState.REFUND_FAIL;
                            } else {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            }

                            retAts.originalCode = status;
                            String originalInfo = tmpJsonResp.getString("errMsg");
                            if (StringHelper.isNullOrEmpty(originalInfo)) {
                                originalInfo = "SUCCESS";
                            }
                            retAts.originalInfo = originalInfo;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", status);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "本次查询失败，请继续查询！";
                        }

                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "银联响应数据格式非法";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }

            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception e) {
            e.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            WriteBankLogLn(e);
        }
        return retAts;
    }

    public RetAtsQryRecRefund queryRecRefundGoods(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
            if (actItem != null) {

                String id = p_reqQryRef.refundNo;
                String qryType = "1";
                if (StringHelper.isNullOrEmpty(id)) {
                    id = p_reqQryRef.oriRdSeq;
                    qryType = "0";
                }
                String url = bankFront.getUrl("queryRecRefundGoods");

                System.setProperty("javax.net.ssl.trustStore", actItem.ownCertFilePath);
                System.setProperty("javax.net.ssl.trustStorePassword", actItem.ownKeyPassword);
                System.setProperty("javax.net.ssl.keyStore", actItem.oppCertFilePath);
                System.setProperty("javax.net.ssl.keyStorePassword", actItem.saltKey);
                TransactionOntimeServiceImplServiceLocator service = new TransactionOntimeServiceImplServiceLocator();
                service.setTransactionOntimeServiceEndpointAddress(url);
                TransactionOntimeServiceImpl client = service.getTransactionOntimeService();

                // id  退货流水号，根据qryType类型填入相应流水
                // qryType  查询方式 0：以用户提交的退货单号查询  1：以提交申请返回的退货流水号查询
                WriteBankLogLn("发送银行的id值为：" + id);
                WriteBankLogLn("发送银行的地址为值为：" + url);
                String tmpStrRet = client.queryGoodsReturnSsl(actItem.userCode, actItem.userFlag, qryType, id);
                WriteBankLogStep3(tmpStrRet);

                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    if (tmpStrRet.length() == 2) {
                        String status = tmpStrRet.substring(0,2);
                        if ("00".equals(status) || "01".equals(status) || "20".equals(status)) {
                            retAts.refundState = RefundState.REFUND_PAYING;
                        } else if ("02".equals(status) || "04".equals(status) || "21".equals(status)) {
                            retAts.refundState = RefundState.REFUND_FAIL;
                        } else if ("09".equals(status)) {
                            retAts.refundState = RefundState.REFUND_SUCCESS;
                        }
                        retAts.respCode = "0";
                        retAts.respInfo = "";
                        retAts.originalCode = status;
                        retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", status);
                    } else {
                        retAts.respCode = "0";
                        retAts.respInfo = "申请失败";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }
}
